Skip to content

Refined rev-share-limit variable names#1874

Open
Goader wants to merge 12 commits intomainfrom
task/refine-rev-share-limit-variable-names
Open

Refined rev-share-limit variable names#1874
Goader wants to merge 12 commits intomainfrom
task/refine-rev-share-limit-variable-names

Conversation

@Goader
Copy link
Copy Markdown
Contributor

@Goader Goader commented Apr 6, 2026

Refined rev-share-limit variable names

closes: #1786

Summary


Why

  • New variable names better represent their meaning

Testing

  • Automatic, CI testing
  • Manual validation

Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

@Goader Goader self-assigned this Apr 6, 2026
@Goader Goader requested a review from a team as a code owner April 6, 2026 10:20
Copilot AI review requested due to automatic review settings April 6, 2026 10:20
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Apr 8, 2026 3:33pm
ensnode.io Skipped Skipped Apr 8, 2026 3:33pm
ensrainbow.io Skipped Skipped Apr 8, 2026 3:33pm

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: 596c497

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 24 packages
Name Type
@namehash/ens-referrals Major
ensapi Major
ensindexer Major
ensadmin Major
ensrainbow Major
fallback-ensapi Major
enssdk Major
enscli Major
enskit Major
ensskills Major
@ensnode/datasources Major
@ensnode/ensrainbow-sdk Major
@ensnode/ensdb-sdk Major
@ensnode/ensnode-react Major
@ensnode/ensnode-sdk Major
@ensnode/ponder-sdk Major
@ensnode/ponder-subgraph Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@docs/mintlify Major
@namehash/namehash-ui Major
@ensnode/enskit-react-example Patch
@ensnode/integration-test-env Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 52a06d7d-8f07-4b9e-86f3-bddfe26ea558

📥 Commits

Reviewing files that changed from the base of the PR and between eaa87bf and 596c497.

📒 Files selected for processing (1)
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts

📝 Walkthrough

Walkthrough

Rename and reshape rev-share-limit and pie-split rule/metric/serialization fields: totalAwardPoolValueawardPool, minQualifiedRevenueContributionminBaseRevenueContribution, qualifiedRevenueSharemaxBaseRevenueShare, standardAwardValueuncappedAward, awardPoolApproxValuecappedAward; add per-edition baseAnnualRevenueContribution (moved from prior global constant). Tests, schemas, serializers, metrics, leaderboard logic, docs, and mocks updated accordingly.

Changes

Cohort / File(s) Summary
Release doc
.changeset/bright-foxes-dance.md
Added changeset documenting API/rule-field renames and a minor release.
Docs / Examples
packages/ens-referrals/README.md
Updated example output and logged fields to use renamed fields (minBaseRevenueContribution, maxBaseRevenueShare, uncappedAward, cappedAward).
Rev-share schemas & validation
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
Replaced rule/metric schema keys, added refinements enforcing relationships (e.g., cappedAward.amount <= uncappedAward.amount, cappedAward.amount <= rules.awardPool.amount), and added unranked/ranked edition refinements.
Rev-share serialized types
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts
Renamed serialized interface properties (totalAwardPoolValueawardPool, minQualifiedRevenueContributionminBaseRevenueContribution), added baseAnnualRevenueContribution, and renamed metric fields to uncappedAward/cappedAward.
Rev-share serialization logic
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts
Serialize new rule and metric field names (awardPool, minBaseRevenueContribution, baseAnnualRevenueContribution, uncappedAward, cappedAward) using serializePriceUsdc.
Rev-share rules & core API
packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts
Updated ReferralProgramRulesRevShareLimit shape and buildReferralProgramRulesRevShareLimit signature to accept awardPool, minBaseRevenueContribution, baseAnnualRevenueContribution, maxBaseRevenueShare; removed global BASE_REVENUE_CONTRIBUTION_PER_YEAR; qualification uses minBaseRevenueContribution.
Rev-share metrics, leaderboard & tests
packages/ens-referrals/src/v1/award-models/rev-share-limit/{metrics.ts,leaderboard.ts,leaderboard.test.ts,edition-metrics.ts,aggregations.ts,api/zod-schemas.test.ts}
Renamed exported fields and function signatures to uncappedAward/cappedAward, pass rules into builders/validators, compute using rules.baseAnnualRevenueContribution and rules.maxBaseRevenueShare, cap awards by rules.awardPool, change ranking key to capped award, and update tests accordingly.
Pie-split schemas, types & metrics
packages/ens-referrals/src/v1/award-models/pie-split/{api/serialize.ts,api/serialized-types.ts,api/zod-schemas.ts,metrics.ts,rules.ts}
Replaced totalAwardPoolValue with awardPool across schema, serialized-types, serializer, rules builder, metric invariants, and validation checks.
Edition defaults
packages/ens-referrals/src/v1/edition-defaults.ts
2026-03 edition now passes baseAnnualRevenueContribution when constructing rev-share-limit rules.
Mocks & app fixtures
apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/mocks-v1.ts
Updated mock leaderboards/fixtures to use rules.awardPool instead of rules.totalAwardPoolValue.
Tests & schema tests
packages/ens-referrals/src/v1/{api/zod-schemas.test.ts,leaderboard-page.test.ts}
Updated test fixtures, schema expectations, and assertions to reflect renamed fields, refined invariants, and adjusted ranking/award behaviors.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client
  participant Leaderboard as LeaderboardBuilder
  participant Rules as RulesModule
  participant Metrics as MetricsBuilder
  participant Serializer as Serializer

  Client->>Leaderboard: request leaderboard
  Leaderboard->>Rules: load rules (awardPool, baseAnnualRevenueContribution, maxBaseRevenueShare)
  Leaderboard->>Metrics: compute per-referrer uncappedAward using rules
  Metrics->>Leaderboard: return uncappedAward
  Leaderboard->>Leaderboard: cap awards (cappedAward = min(uncappedAward, awardPoolRemaining))
  Leaderboard->>Serializer: serialize rules + referrer metrics (awardPool, uncappedAward, cappedAward)
  Serializer->>Client: respond with serialized leaderboard
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • namehash/ensnode#1663: Renames/refactors the same rev-share-limit award-model code and moves base revenue contribution into rules — strong overlap.
  • namehash/ensnode#1712: Modifies rev-share-limit rules/qualification logic and touches related serializers/schemas — likely intersecting.
  • namehash/ensnode#1780: Adjusts award-model shapes/builders and touches the same modules (edition summaries, awardPool handling) — directly related.

Suggested labels

ensanalytics

Poem

🐇 I hopped through fields and nudged each name,
"total" to "award", made the rules less tame.
Uncapped and capped, base and max in a row,
Tests and docs twitched their whiskers and said "Let's go!"
A carrot-coded change — tidy, quick, and aglow. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Refined rev-share-limit variable names' clearly and concisely summarizes the main change of the pull request.
Description check ✅ Passed The PR description follows the template with all required sections completed: Summary, Why, Testing, and Pre-Review Checklist are all present and properly filled.
Linked Issues check ✅ Passed The PR successfully implements all objectives from issue #1786: renaming minQualifiedRevenueContribution→minBaseRevenueContribution, qualifiedRevenueShare→maxBaseRevenueShare, standardAwardValue→uncappedAward, and awardPoolApproxValue→cappedAward across the codebase.
Out of Scope Changes check ✅ Passed All changes are directly related to the variable renaming objectives in issue #1786; the PR also consistently renamed totalAwardPoolValue→awardPool across both RevShareLimit and PieSplit award models, which is a reasonable extension of the refactoring scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task/refine-rev-share-limit-variable-names

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 6, 2026

Greptile Summary

This PR is a pure rename/refactoring across the rev-share-limit award model, replacing four field names with clearer equivalents: minQualifiedRevenueContributionminBaseRevenueContribution, qualifiedRevenueSharemaxBaseRevenueShare, standardAwardValueuncappedAwardValue, and awardPoolApproxValuecappedAwardValue. The changes are applied consistently across TypeScript interfaces, Zod schemas, serializers, serialized types, tests, and README documentation.

  • All 10 changed files are updated coherently — no stale references to old names remain in logic or type definitions
  • Internal race-algorithm state variables (e.g., qualifiedAwardValueAmount) are correctly left unchanged as they are private implementation details, not part of the public API
  • The changeset version bump is marked minor; since the package is at v1.9.0 and these are breaking public API field renames (serialized API responses, exported TypeScript types, and README examples all change), a major bump would be more appropriate under strict semver

Confidence Score: 5/5

Safe to merge — all renames are applied consistently with no stale references or logic changes.

All 10 changed files are internally consistent with the new field names. No logic was altered — only identifier names. The sole open question is the semver bump level, which is a P2 style concern that does not block merge.

Only .changeset/bright-foxes-dance.md warrants a second look regarding whether minor is the correct bump level for a post-1.0.0 package with public API field renames.

Important Files Changed

Filename Overview
.changeset/bright-foxes-dance.md Changeset marks renaming of public API fields as 'minor' rather than 'major' for a post-1.0.0 package
packages/ens-referrals/README.md Documentation updated to reflect all four new field names consistently
packages/ens-referrals/src/v1/api/zod-schemas.test.ts Test data and type annotations updated to use minBaseRevenueContribution and maxBaseRevenueShare
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts Serialization functions correctly reference the renamed fields throughout
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts Serialized TypeScript interfaces updated to use uncappedAwardValue and cappedAwardValue
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts Zod validation schemas updated to reference minBaseRevenueContribution and maxBaseRevenueShare
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts All test assertions migrated from awardPoolApproxValue/standardAwardValue to cappedAwardValue/uncappedAwardValue
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts Leaderboard builder uses maxBaseRevenueShare; internal race-state variable qualifiedAwardValueAmount left unchanged
packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts Metrics interfaces and builders fully updated; uncappedAwardValue and cappedAwardValue replace old names
packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts Rules interface and validator correctly use minBaseRevenueContribution and maxBaseRevenueShare

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ReferralEvent input] --> B[buildReferrerLeaderboardRevShareLimit]
    B --> C{isReferrerQualifiedRevShareLimit}
    C -->|threshold check| D[rules.minBaseRevenueContribution]
    C -->|renamed from minQualifiedRevenueContribution| D
    B --> E[scalePrice]
    E -->|share fraction| F[rules.maxBaseRevenueShare]
    F -->|renamed from qualifiedRevenueShare| F
    B --> G[buildAwardedReferrerMetricsRevShareLimit]
    G --> H[uncappedAwardValue\nmaxBaseRevenueShare × totalBaseRevenueContribution\nrenamed from standardAwardValue]
    G --> I[cappedAwardValue\npool-capped actual award\nrenamed from awardPoolApproxValue]
    G --> J[ReferrerLeaderboardRevShareLimit output]
    J --> K[rules: minBaseRevenueContribution\nrules: maxBaseRevenueShare]
    J --> L[referrers: uncappedAwardValue\nreferrers: cappedAwardValue]
Loading

Reviews (1): Last reviewed commit: "renamed variables" | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Renames rev-share-limit rule/metric field names across the v1 referrals API to better reflect meaning (per #1786).

Changes:

  • Renamed RevShareLimit rule fields: minQualifiedRevenueContributionminBaseRevenueContribution, qualifiedRevenueSharemaxBaseRevenueShare.
  • Renamed RevShareLimit awarded metric fields: standardAwardValueuncappedAwardValue, awardPoolApproxValuecappedAwardValue.
  • Updated validation, serialization/Zod schemas, tests, and README examples to use the new names.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts Renames rule fields and updates validation/qualification logic to match.
packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts Renames awarded metric fields and updates invariants/validation/builders.
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts Updates award computation to use renamed rule/metric fields.
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts Updates RevShareLimit leaderboard tests for renamed fields.
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts Updates RevShareLimit Zod schemas and refinements for renamed fields.
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts Updates serialized type names for renamed fields.
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts Updates RevShareLimit serializers to emit renamed fields.
packages/ens-referrals/src/v1/api/zod-schemas.test.ts Updates v1 API schema tests to use renamed RevShareLimit fields.
packages/ens-referrals/README.md Updates public docs/examples to the renamed fields.
.changeset/bright-foxes-dance.md Declares a release bump for the API field renames.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts (1)

72-77: ⚠️ Potential issue | 🟡 Minor

Replace the stale awardPoolShare term in this invariant.

That name is no longer exposed by this type or the rest of the renamed API, so the doc now points readers at the wrong concept.

Doc-only cleanup
-   * Identifies if the referrer meets the qualifications of the {`@link` ReferralProgramRulesRevShareLimit} to receive a non-zero `awardPoolShare`.
+   * Identifies if the referrer meets the qualifications of the {`@link` ReferralProgramRulesRevShareLimit} to receive a non-zero award.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts` around
lines 72 - 77, Update the JSDoc invariant to use the current API term instead of
the stale `awardPoolShare` identifier; replace `awardPoolShare` with the renamed
property `awardShare` in the comment that describes the invariant for
ReferralProgramRulesRevShareLimit (the block referencing
`totalBaseRevenueContribution` and `isAdminDisqualified`) so the docs point at
the correct concept.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`:
- Around line 126-137: The Zod schema must mirror
validateUnrankedReferrerMetricsRevShareLimit by rejecting any "unranked" record
whose uncappedAwardValue.amount or cappedAwardValue.amount is non-zero; update
the schema block that defines uncappedAwardValue, cappedAwardValue,
isAdminDisqualified, adminDisqualificationReason (the schema using valueLabel)
to add an additional .refine predicate that checks "if this record is unranked
(use the same unranked condition used in
validateUnrankedReferrerMetricsRevShareLimit) then uncappedAwardValue.amount ===
0 && cappedAwardValue.amount === 0", and return a clear message/path (e.g.,
path: ["uncappedAwardValue","cappedAwardValue"]) when violated so the serialized
API shape matches the runtime validator.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 188-210: The validator in metrics.ts enforces
cappedAwardValue.amount == 0n only for admin-disqualified referrers but misses
the contract that when metrics.isQualified === false (below-threshold)
cappedAwardValue must also be zero; update the validation logic after the
makePriceUsdcSchema parses to add a check for metrics.isQualified === false that
throws a descriptive Error if metrics.cappedAwardValue.amount !== 0n (similar to
the existing isAdminDisqualified check), referencing the same properties
(metrics.isQualified, metrics.cappedAwardValue.amount) and keeping the other
comparisons against rules.totalAwardPoolValue.amount and
metrics.uncappedAwardValue.amount intact.

---

Outside diff comments:
In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 72-77: Update the JSDoc invariant to use the current API term
instead of the stale `awardPoolShare` identifier; replace `awardPoolShare` with
the renamed property `awardShare` in the comment that describes the invariant
for ReferralProgramRulesRevShareLimit (the block referencing
`totalBaseRevenueContribution` and `isAdminDisqualified`) so the docs point at
the correct concept.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8b1dd26f-f231-448b-a5c1-88e14a85bd69

📥 Commits

Reviewing files that changed from the base of the PR and between d0c97a5 and f5b4ecc.

📒 Files selected for processing (10)
  • .changeset/bright-foxes-dance.md
  • packages/ens-referrals/README.md
  • packages/ens-referrals/src/v1/api/zod-schemas.test.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts

@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 6, 2026 15:49 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 6, 2026 15:49 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 6, 2026 15:49 Inactive
Copilot AI review requested due to automatic review settings April 6, 2026 16:19
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 6, 2026 16:19 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 6, 2026 16:19 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 6, 2026 16:19 Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`:
- Around line 139-145: The current .refine call incorrectly sets path to
["uncappedAwardValue","cappedAwardValue"] (which points to a nested path);
replace the .refine with .superRefine on the same Zod schema and, inside the
callback, check the same condition and call ctx.addIssue separately for each
offending sibling field (use paths ["uncappedAwardValue"] and
["cappedAwardValue"] respectively) with the appropriate message; use
ZodIssueCode.custom for the issues so each field gets its own validation error
instead of a nonexistent nested path.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 189-195: The current validator for
AwardedReferrerMetricsRevShareLimit.uncappedAwardValue only parses a PriceUsdc
but should enforce the documented invariant; compute expectedUncapped =
rules.maxBaseRevenueShare × metrics.totalBaseRevenueContribution inside the
validation logic (using the same numeric types/scale as makePriceUsdcSchema
expects) and either assert parsed uncappedAwardValue equals expectedUncapped or,
better, derive and set uncappedAwardValue from that computation instead of
trusting caller input; update
makePriceUsdcSchema("AwardedReferrerMetricsRevShareLimit.cappedAwardValue")
usage to still validate cappedAwardValue <= expectedUncapped and adjust
buildAwardedReferrerMetricsRevShareLimit() to derive uncappedAwardValue from
rules.maxBaseRevenueShare and metrics.totalBaseRevenueContribution.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 46afcbc6-f698-4608-9a08-24db3381105a

📥 Commits

Reviewing files that changed from the base of the PR and between ae807a6 and 1443e64.

📒 Files selected for processing (2)
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts

@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 6, 2026 18:28 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 6, 2026 18:28 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 6, 2026 18:28 Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts (1)

120-146: ⚠️ Potential issue | 🟠 Major

Mirror the rest of the unranked zero-metric contract in this schema.

validateUnrankedReferrerMetricsRevShareLimit() still rejects non-zero totalReferrals, totalIncrementalDuration, totalRevenueContribution.amount, and totalBaseRevenueContribution.amount, but this schema only encodes the zero-award checks. That leaves the serialized API shape looser than the runtime model and allows invalid unranked payloads to parse here.

Suggested schema tightening
     .object({
       referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
       totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
       totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
       totalRevenueContribution: makePriceEthSchema(`${valueLabel}.totalRevenueContribution`),
       totalBaseRevenueContribution: makePriceUsdcSchema(
         `${valueLabel}.totalBaseRevenueContribution`,
       ),
       rank: z.null(),
       isQualified: z.literal(false),
       uncappedAwardValue: makePriceUsdcSchema(`${valueLabel}.uncappedAwardValue`),
       cappedAwardValue: makePriceUsdcSchema(`${valueLabel}.cappedAwardValue`),
       isAdminDisqualified: z.boolean(),
       adminDisqualificationReason: z
         .string()
         .trim()
         .min(1, `${valueLabel}.adminDisqualificationReason must not be empty`)
         .nullable(),
     })
+    .refine((data) => data.totalReferrals === 0, {
+      message: `${valueLabel}.totalReferrals must be 0 for unranked referrers`,
+      path: ["totalReferrals"],
+    })
+    .refine((data) => data.totalIncrementalDuration === 0, {
+      message: `${valueLabel}.totalIncrementalDuration must be 0 for unranked referrers`,
+      path: ["totalIncrementalDuration"],
+    })
+    .refine((data) => data.totalRevenueContribution.amount === 0n, {
+      message: `${valueLabel}.totalRevenueContribution must be 0 for unranked referrers`,
+      path: ["totalRevenueContribution"],
+    })
+    .refine((data) => data.totalBaseRevenueContribution.amount === 0n, {
+      message: `${valueLabel}.totalBaseRevenueContribution must be 0 for unranked referrers`,
+      path: ["totalBaseRevenueContribution"],
+    })
     .refine((data) => data.uncappedAwardValue.amount === 0n, {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`
around lines 120 - 146, The schema for unranked referrers currently only
enforces zero award values but must also mirror the runtime validator
validateUnrankedReferrerMetricsRevShareLimit: add checks to the zod object
(around the same chain where rank is z.null() and isQualified is
z.literal(false)) to require totalReferrals === 0, totalIncrementalDuration ===
0 (or duration.amount === 0 depending on the duration shape),
totalRevenueContribution.amount === 0n, and totalBaseRevenueContribution.amount
=== 0n; implement these as additional .refine() calls (or a single
.superRefine()) referencing the fields totalReferrals, totalIncrementalDuration,
totalRevenueContribution, and totalBaseRevenueContribution so the parsed API
shape matches the runtime validation.
♻️ Duplicate comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts (1)

189-195: ⚠️ Potential issue | 🟠 Major

Don't accept an arbitrary uncappedAwardValue here.

This field is documented as rules.maxBaseRevenueShare × totalBaseRevenueContribution, but the validator only parses it as a generic PriceUsdc and the builder still takes it from callers. Any inflated uncappedAwardValue currently passes as long as cappedAwardValue <= uncappedAwardValue, which weakens the renamed contract. Recompute the expected uncapped amount from rules.maxBaseRevenueShare and totalBaseRevenueContribution here, or derive it inside buildAwardedReferrerMetricsRevShareLimit() instead of accepting it as input. Based on learnings: In packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts, AwardedReferrerMetricsRevShareLimit.standardAwardValue should not duplicate the generic PriceUsdc non-negative invariant; keep only the context-specific formula (“rules.qualifiedRevenueShare × totalBaseRevenueContribution”) and notes about pool independence.

Also applies to: 222-231

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts` around
lines 189 - 195, The code currently accepts an arbitrary uncappedAwardValue and
only validates it as a generic PriceUsdc; instead recompute and validate
uncappedAwardValue from the formula rules.maxBaseRevenueShare ×
totalBaseRevenueContribution (or move that derivation into
buildAwardedReferrerMetricsRevShareLimit()) and validate the computed value
against cappedAwardValue, rather than trusting caller input for
AwardedReferrerMetricsRevShareLimit.uncappedAwardValue; likewise remove the
redundant generic non-negative PriceUsdc check for
AwardedReferrerMetricsRevShareLimit.standardAwardValue and keep only the
context-specific invariant/description that it equals
rules.qualifiedRevenueShare × totalBaseRevenueContribution and is
pool-independent. Ensure references to makePriceUsdcSchema, cappedAwardValue,
standardAwardValue, buildAwardedReferrerMetricsRevShareLimit,
rules.maxBaseRevenueShare, rules.qualifiedRevenueShare, and
totalBaseRevenueContribution are used to locate and update the logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`:
- Around line 120-146: The schema for unranked referrers currently only enforces
zero award values but must also mirror the runtime validator
validateUnrankedReferrerMetricsRevShareLimit: add checks to the zod object
(around the same chain where rank is z.null() and isQualified is
z.literal(false)) to require totalReferrals === 0, totalIncrementalDuration ===
0 (or duration.amount === 0 depending on the duration shape),
totalRevenueContribution.amount === 0n, and totalBaseRevenueContribution.amount
=== 0n; implement these as additional .refine() calls (or a single
.superRefine()) referencing the fields totalReferrals, totalIncrementalDuration,
totalRevenueContribution, and totalBaseRevenueContribution so the parsed API
shape matches the runtime validation.

---

Duplicate comments:
In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 189-195: The code currently accepts an arbitrary
uncappedAwardValue and only validates it as a generic PriceUsdc; instead
recompute and validate uncappedAwardValue from the formula
rules.maxBaseRevenueShare × totalBaseRevenueContribution (or move that
derivation into buildAwardedReferrerMetricsRevShareLimit()) and validate the
computed value against cappedAwardValue, rather than trusting caller input for
AwardedReferrerMetricsRevShareLimit.uncappedAwardValue; likewise remove the
redundant generic non-negative PriceUsdc check for
AwardedReferrerMetricsRevShareLimit.standardAwardValue and keep only the
context-specific invariant/description that it equals
rules.qualifiedRevenueShare × totalBaseRevenueContribution and is
pool-independent. Ensure references to makePriceUsdcSchema, cappedAwardValue,
standardAwardValue, buildAwardedReferrerMetricsRevShareLimit,
rules.maxBaseRevenueShare, rules.qualifiedRevenueShare, and
totalBaseRevenueContribution are used to locate and update the logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e0628e2-9060-4a54-a071-462eaecf1002

📥 Commits

Reviewing files that changed from the base of the PR and between 1443e64 and fb767c2.

📒 Files selected for processing (2)
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts

@Goader Goader requested a review from lightwalker-eth April 6, 2026 18:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts (1)

120-144: 🛠️ Refactor suggestion | 🟠 Major

Replace positional builder parameters with a named params object.

awardPool, minBaseRevenueContribution, and baseAnnualRevenueContribution are all PriceUsdc. Reordering any two compiles silently and changes the award/qualification math. This PR added a third USDC slot, and both edition-defaults.ts and leaderboard.test.ts now call the builder with three consecutive positional USDC arguments.

♻️ Suggested shape
+type BuildReferralProgramRulesRevShareLimitParams = {
+  awardPool: PriceUsdc;
+  minBaseRevenueContribution: PriceUsdc;
+  baseAnnualRevenueContribution: PriceUsdc;
+  maxBaseRevenueShare: number;
+  startTime: UnixTimestamp;
+  endTime: UnixTimestamp;
+  subregistryId: AccountId;
+  rulesUrl: URL;
+  areAwardsDistributed: boolean;
+  disqualifications?: ReferralProgramEditionDisqualification[];
+};
+
-export const buildReferralProgramRulesRevShareLimit = (
-  awardPool: PriceUsdc,
-  minBaseRevenueContribution: PriceUsdc,
-  baseAnnualRevenueContribution: PriceUsdc,
-  maxBaseRevenueShare: number,
-  startTime: UnixTimestamp,
-  endTime: UnixTimestamp,
-  subregistryId: AccountId,
-  rulesUrl: URL,
-  areAwardsDistributed: boolean,
-  disqualifications: ReferralProgramEditionDisqualification[] = [],
-): ReferralProgramRulesRevShareLimit => {
+export const buildReferralProgramRulesRevShareLimit = ({
+  awardPool,
+  minBaseRevenueContribution,
+  baseAnnualRevenueContribution,
+  maxBaseRevenueShare,
+  startTime,
+  endTime,
+  subregistryId,
+  rulesUrl,
+  areAwardsDistributed,
+  disqualifications = [],
+}: BuildReferralProgramRulesRevShareLimitParams): ReferralProgramRulesRevShareLimit => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts` around
lines 120 - 144, The builder buildReferralProgramRulesRevShareLimit currently
takes multiple positional PriceUsdc params that are easy to swap; change its
signature to accept a single named-params object (e.g. { awardPool,
minBaseRevenueContribution, baseAnnualRevenueContribution, maxBaseRevenueShare,
startTime, endTime, subregistryId, rulesUrl, areAwardsDistributed,
disqualifications }) and use those properties when constructing result; then
update all callers (notably edition-defaults.ts and leaderboard.test.ts) to pass
an object with explicit field names instead of positional arguments to prevent
silent reordering bugs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts`:
- Around line 120-144: The builder buildReferralProgramRulesRevShareLimit
currently takes multiple positional PriceUsdc params that are easy to swap;
change its signature to accept a single named-params object (e.g. { awardPool,
minBaseRevenueContribution, baseAnnualRevenueContribution, maxBaseRevenueShare,
startTime, endTime, subregistryId, rulesUrl, areAwardsDistributed,
disqualifications }) and use those properties when constructing result; then
update all callers (notably edition-defaults.ts and leaderboard.test.ts) to pass
an object with explicit field names instead of positional arguments to prevent
silent reordering bugs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1ba722e2-9498-46f3-90b4-486729d18623

📥 Commits

Reviewing files that changed from the base of the PR and between fb767c2 and 4770420.

📒 Files selected for processing (19)
  • .changeset/bright-foxes-dance.md
  • apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/mocks-v1.ts
  • packages/ens-referrals/README.md
  • packages/ens-referrals/src/v1/api/zod-schemas.test.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/api/serialize.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/api/serialized-types.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/metrics.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/rules.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts
  • packages/ens-referrals/src/v1/edition-defaults.ts
  • packages/ens-referrals/src/v1/leaderboard-page.test.ts

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 8, 2026 11:34 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 8, 2026 11:34 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 8, 2026 11:34 Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts (1)

191-209: ⚠️ Potential issue | 🟠 Major

Mirror the award-pool ceiling in the composite schemas.

validateAwardedReferrerMetricsRevShareLimit() rejects cappedAwardValue.amount > rules.awardPool.amount, but these parent schemas still accept those payloads because the child schema cannot see rules. That leaves the serialized API surface looser than the runtime model.

Suggested fix
 export const makeReferrerEditionMetricsRankedRevShareLimitSchema = (
   valueLabel: string = "ReferrerEditionMetricsRankedRevShareLimit",
 ) =>
   z
     .object({
       awardModel: z.literal(ReferralProgramAwardModels.RevShareLimit),
       type: z.literal(ReferrerEditionMetricsTypeIds.Ranked),
       rules: makeReferralProgramRulesRevShareLimitSchema(`${valueLabel}.rules`),
       referrer: makeAwardedReferrerMetricsRevShareLimitSchema(`${valueLabel}.referrer`),
       aggregatedMetrics: makeAggregatedReferrerMetricsRevShareLimitSchema(
         `${valueLabel}.aggregatedMetrics`,
       ),
       status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
       accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`),
     })
+    .refine((data) => data.referrer.cappedAwardValue.amount <= data.rules.awardPool.amount, {
+      message: `${valueLabel}.referrer.cappedAwardValue must be <= ${valueLabel}.rules.awardPool`,
+      path: ["referrer", "cappedAwardValue"],
+    })
     .refine((data) => data.awardModel === data.rules.awardModel, {
       message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
       path: ["awardModel"],
     });

 export const makeReferrerLeaderboardPageRevShareLimitSchema = (
   valueLabel: string = "ReferrerLeaderboardPageRevShareLimit",
 ) =>
   makeBaseReferrerLeaderboardPageSchema(valueLabel)
     .safeExtend({
       awardModel: z.literal(ReferralProgramAwardModels.RevShareLimit),
       rules: makeReferralProgramRulesRevShareLimitSchema(`${valueLabel}.rules`),
       referrers: z.array(
         makeAwardedReferrerMetricsRevShareLimitSchema(`${valueLabel}.referrers[record]`),
       ),
       aggregatedMetrics: makeAggregatedReferrerMetricsRevShareLimitSchema(
         `${valueLabel}.aggregatedMetrics`,
       ),
     })
+    .superRefine((data, ctx) => {
+      data.referrers.forEach((referrer, index) => {
+        if (referrer.cappedAwardValue.amount > data.rules.awardPool.amount) {
+          ctx.addIssue({
+            code: z.ZodIssueCode.custom,
+            message: `${valueLabel}.referrers[${index}].cappedAwardValue must be <= ${valueLabel}.rules.awardPool`,
+            path: ["referrers", index, "cappedAwardValue"],
+          });
+        }
+      });
+    })
     .refine((data) => data.awardModel === data.rules.awardModel, {
       message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
       path: ["awardModel"],
     });

Also applies to: 266-283

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`
around lines 191 - 209, The composite schema
makeReferrerEditionMetricsRankedRevShareLimitSchema currently only checks
awardModel equality but must also enforce the award-pool ceiling: add a .refine
that compares data.referrer.cappedAwardValue.amount (when present) against
data.rules.awardPool.amount and fails if cappedAwardValue.amount >
rules.awardPool.amount, returning a clear message/path (e.g., path
["referrer","cappedAwardValue","amount"]). Apply the same additional refine to
the corresponding composite schema(s) mentioned (the one at lines 266-283) so
child validation that depends on rules.awardPool is enforced at the parent level
as well.
♻️ Duplicate comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts (1)

160-166: ⚠️ Potential issue | 🟠 Major

Derive uncappedAwardValue instead of accepting it as input.

This field is documented as maxBaseRevenueShare × totalBaseRevenueContribution, but validateAwardedReferrerMetricsRevShareLimit() only parses a generic PriceUsdc and buildAwardedReferrerMetricsRevShareLimit() still trusts the caller. That lets internally inconsistent awarded rows pass as long as cappedAwardValue.amount <= uncappedAwardValue.amount. Please compute it from rules.maxBaseRevenueShare in the builder, or at least recompute and compare it during validation.

Also applies to: 188-190, 221-233

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts` around
lines 160 - 166, The uncappedAwardValue field is being accepted from input
instead of being derived, allowing inconsistent rows; update
buildAwardedReferrerMetricsRevShareLimit to compute uncappedAwardValue as
rules.maxBaseRevenueShare × totalBaseRevenueContribution (use the same PriceUsdc
math used elsewhere) and remove/ignore any incoming uncappedAwardValue, and
update validateAwardedReferrerMetricsRevShareLimit to recompute
uncappedAwardValue from rules.maxBaseRevenueShare and compare it against the
provided cappedAwardValue (and fail if cappedAwardValue.amount > derived
uncappedAwardValue.amount); apply the same change to the other affected spots
referenced around lines 188-190 and 221-233 so uncappedAwardValue is always
derived from rules.maxBaseRevenueShare and totalBaseRevenueContribution rather
than trusted from input.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 71-76: The doc comment for the eligibility predicate incorrectly
states a non-zero payout; update the summary and invariant for the
function/field that references ReferralProgramRulesRevShareLimit so it describes
rule-based eligibility only (i.e., that totalBaseRevenueContribution >=
minBaseRevenueContribution and isAdminDisqualified is false) and explicitly omit
any guarantee about cappedAwardValue.amount being non-zero (since the pool may
be exhausted). Ensure the wording mentions eligibility under the rules rather
than a guaranteed non-zero payout and keep references to
totalBaseRevenueContribution,
ReferralProgramRulesRevShareLimit.minBaseRevenueContribution,
isAdminDisqualified, and cappedAwardValue.amount so maintainers can locate the
related logic.

---

Outside diff comments:
In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`:
- Around line 191-209: The composite schema
makeReferrerEditionMetricsRankedRevShareLimitSchema currently only checks
awardModel equality but must also enforce the award-pool ceiling: add a .refine
that compares data.referrer.cappedAwardValue.amount (when present) against
data.rules.awardPool.amount and fails if cappedAwardValue.amount >
rules.awardPool.amount, returning a clear message/path (e.g., path
["referrer","cappedAwardValue","amount"]). Apply the same additional refine to
the corresponding composite schema(s) mentioned (the one at lines 266-283) so
child validation that depends on rules.awardPool is enforced at the parent level
as well.

---

Duplicate comments:
In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 160-166: The uncappedAwardValue field is being accepted from input
instead of being derived, allowing inconsistent rows; update
buildAwardedReferrerMetricsRevShareLimit to compute uncappedAwardValue as
rules.maxBaseRevenueShare × totalBaseRevenueContribution (use the same PriceUsdc
math used elsewhere) and remove/ignore any incoming uncappedAwardValue, and
update validateAwardedReferrerMetricsRevShareLimit to recompute
uncappedAwardValue from rules.maxBaseRevenueShare and compare it against the
provided cappedAwardValue (and fail if cappedAwardValue.amount > derived
uncappedAwardValue.amount); apply the same change to the other affected spots
referenced around lines 188-190 and 221-233 so uncappedAwardValue is always
derived from rules.maxBaseRevenueShare and totalBaseRevenueContribution rather
than trusted from input.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4650b688-71a2-4791-8f22-23be55aaa5d7

📥 Commits

Reviewing files that changed from the base of the PR and between fb767c2 and 59ac11e.

📒 Files selected for processing (19)
  • .changeset/bright-foxes-dance.md
  • apps/ensapi/src/lib/ensanalytics/referrer-leaderboard/mocks-v1.ts
  • packages/ens-referrals/README.md
  • packages/ens-referrals/src/v1/api/zod-schemas.test.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/api/serialize.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/api/serialized-types.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/metrics.ts
  • packages/ens-referrals/src/v1/award-models/pie-split/rules.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/rules.ts
  • packages/ens-referrals/src/v1/edition-defaults.ts
  • packages/ens-referrals/src/v1/leaderboard-page.test.ts

Copilot AI review requested due to automatic review settings April 8, 2026 13:39
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 8, 2026 13:39 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 8, 2026 13:39 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 8, 2026 13:39 Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts (1)

192-198: ⚠️ Potential issue | 🟠 Major

Derive uncappedAwardValue from the rules instead of trusting caller input.

Line 192 only validates uncappedAwardValue as a generic PriceUsdc, and Line 227 still lets callers pass any value. That breaks the documented maxBaseRevenueShare × totalBaseRevenueContribution invariant and can incorrectly widen or shrink the ceiling enforced by cappedAwardValue <= uncappedAwardValue. Since breaking changes are still acceptable in this package, I’d remove uncappedAwardValue from the builder input and recompute/validate it from rules.maxBaseRevenueShare and referrer.totalBaseRevenueContribution.

Based on learnings: AwardedReferrerMetricsRevShareLimit.standardAwardValue should not duplicate the generic PriceUsdc non-negative invariant; keep only the context-specific formula ("rules.qualifiedRevenueShare × totalBaseRevenueContribution") and notes about pool independence.

Also applies to: 225-235

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts` around
lines 192 - 198, Remove uncappedAwardValue from the
AwardedReferrerMetricsRevShareLimit builder input and stop trusting
caller-provided values; instead compute uncappedAwardValue as
rules.maxBaseRevenueShare × referrer.totalBaseRevenueContribution inside the
builder/constructor, then validate that computed value with makePriceUsdcSchema
before using it to enforce cappedAwardValue <= uncappedAwardValue. Update any
code paths that currently parse/validate incoming uncappedAwardValue (lines
referencing AwardedReferrerMetricsRevShareLimit.uncappedAwardValue) to use the
recomputed value, and remove the redundant non-negative check on
standardAwardValue so it only documents/validates the context-specific formula
(rules.qualifiedRevenueShare × totalBaseRevenueContribution).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts`:
- Around line 192-198: Remove uncappedAwardValue from the
AwardedReferrerMetricsRevShareLimit builder input and stop trusting
caller-provided values; instead compute uncappedAwardValue as
rules.maxBaseRevenueShare × referrer.totalBaseRevenueContribution inside the
builder/constructor, then validate that computed value with makePriceUsdcSchema
before using it to enforce cappedAwardValue <= uncappedAwardValue. Update any
code paths that currently parse/validate incoming uncappedAwardValue (lines
referencing AwardedReferrerMetricsRevShareLimit.uncappedAwardValue) to use the
recomputed value, and remove the redundant non-negative check on
standardAwardValue so it only documents/validates the context-specific formula
(rules.qualifiedRevenueShare × totalBaseRevenueContribution).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 48316956-f5a9-4f03-9614-63639bda3bd7

📥 Commits

Reviewing files that changed from the base of the PR and between 59ac11e and 28ec732.

📒 Files selected for processing (2)
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts`:
- Around line 286-293: Replace the current .refine(...) call with
.superRefine(...) on the schema and, inside the callback, iterate over
data.referrers with their index and for each referrer whose cappedAward.amount >
data.rules.awardPool.amount call ctx.addIssue with code: z.ZodIssueCode.custom
(or use ctx.addIssue({ message: ..., path: [...] })) and set the path to
["referrers", index, "cappedAward", "amount"] so the error points to the exact
referrer; use the same message template
`${valueLabel}.referrers[${index}].cappedAward must be <=
${valueLabel}.rules.awardPool` referencing data.rules.awardPool.amount and
ensure you import/use z from zod in the same module (replace the existing refine
on that schema with this superRefine logic).

In `@packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts`:
- Around line 154-164: The current already-qualified branch computes each
event's claim from the event delta (incrementalBaseRevenueAmount ->
incrementalUncappedAward via priceUsdc and scalePrice) which reintroduces
rounding on every event; instead compute the new cumulative uncapped award,
subtract the previously processed cumulative uncapped award, and claim that
difference so rounding happens only once per cumulative total. Concretely:
derive a cumulativeUncappedTotal using priceUsdc and scalePrice against the
cumulative baseAnnualRevenueContribution (or cumulative duration) and
rules.maxBaseRevenueShare, compute deltaUncapped = cumulativeUncappedTotal -
state.previousUncappedTotal, then cap that delta against poolRemainingAmount,
add to state.cappedAwardAmount, decrement poolRemainingAmount, and update
state.previousUncappedTotal; also add a regression test that sends many small
incremental events verifying the final cappedAward equals the uncapped total
when pool is not exhausted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 483c859c-3019-451b-b54f-808dcc59664f

📥 Commits

Reviewing files that changed from the base of the PR and between 28ec732 and eaa87bf.

📒 Files selected for processing (11)
  • .changeset/bright-foxes-dance.md
  • packages/ens-referrals/README.md
  • packages/ens-referrals/src/v1/api/zod-schemas.test.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/aggregations.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialize.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/serialized-types.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/api/zod-schemas.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/edition-metrics.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts

Copilot AI review requested due to automatic review settings April 8, 2026 15:33
@vercel vercel bot temporarily deployed to Preview – ensnode.io April 8, 2026 15:33 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io April 8, 2026 15:33 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io April 8, 2026 15:33 Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Goader Goader requested a review from lightwalker-eth April 8, 2026 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refine rev-share-limit variable names

3 participants